package com.qf.main.login.config;

import com.qf.main.login.realm.CodeRealm;
import com.qf.main.login.realm.MyModularRealmAuthenticator;
import com.qf.main.login.realm.SysUserRealm;
import com.qf.main.login.session.CustomSessionManager;
import com.qf.main.login.utils.ShiroUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import java.util.ArrayList;
import java.util.List;

/**
 * @author chengqiang
 * @Create 2024-01-15-17:16
 * @Description: 1.  注册自动 Realm
 * 2.  注册 SecurityManager
 * 3.  白名单过滤器 ShiroFilterChainDefinition
 * 4.  注册密码加密器
 */
@Configuration
// @EnableAspectJAutoProxy(proxyTargetClass = true)
public class ShiroConfig {

    public static final String SHIRO_ANON = "anon";
    public static final String SHIRO_AUTHC = "authc";
    @Value("${shiro.white.list}")
    private List<String> whiteList;
    @Value("${shiro.antPath}")
    private String antPath;

    /**
     * 容器中注册
     * realm存储着验证方式
     *
     * @return
     */
    @Bean
    public SysUserRealm sysUserRealm(HashedCredentialsMatcher hashedCredentialsMatcher) {
        SysUserRealm userRealm = new SysUserRealm();
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return userRealm;
    }

    @Bean
    public CodeRealm codeRealm(HashedCredentialsMatcher hashedCredentialsMatcher) {
        CodeRealm Realm = new CodeRealm();
        Realm.setCredentialsMatcher(hashedCredentialsMatcher);
        return Realm;
    }



    /**
     * 自定义的Realm管理，主要针对多realm
     */
    @Bean("myModularRealmAuthenticator")
    public MyModularRealmAuthenticator modularRealmAuthenticator() {
        MyModularRealmAuthenticator customizedModularRealmAuthenticator = new MyModularRealmAuthenticator();
        // 设置realm判断条件
        customizedModularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return customizedModularRealmAuthenticator;
    }

    /**
     *
     */

    @Bean
    public DefaultWebSecurityManager securityManager(SysUserRealm  sysUserRealm ,CodeRealm codeRealm, CustomSessionManager customSessionManager) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();

        List<Realm> realms = new ArrayList<>();
        // 统一角色权限控制realm
        realms.add(codeRealm);
        // 用户密码登录realm
        realms.add(sysUserRealm);


        // 注册自定义Realm
        defaultWebSecurityManager.setRealms(realms);
        // defaultWebSecurityManager.setRealm(realm);
        defaultWebSecurityManager.setSessionManager(customSessionManager);
        // defaultWebSecurityManager
        return defaultWebSecurityManager;
    }
    // 开启权限
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }


    /**
     * 1. 过滤白名单
     * 2.
     */
    // @Bean
    // public ShiroFilterChainDefinition shiroFilterChainDefinition() {
    //
    //     DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
    //     whiteList.forEach(path -> definition.addPathDefinition(path, SHIRO_ANON));
    //     definition.addPathDefinition("/**", SHIRO_AUTHC);
    //     return definition;
    // }
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
        // 白名单

        whiteList.forEach(path -> definition.addPathDefinition(path, SHIRO_ANON));
        // 表示其他所有接口的需要认证
        // definition.addPathDefinition(antPath, SHIRO_AUTHC);
        // definition.addPathDefinitions();
        return definition;
    }


    // 加密方法，
    // 将realm加入容器
    // 白名单

    /**
     * 注册到容器
     *
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 加密方式
        hashedCredentialsMatcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
        // 加密次数
        hashedCredentialsMatcher.setHashIterations(ShiroUtils.HASH_ITERATIONS);
        return hashedCredentialsMatcher;
    }


    @Bean
    public CustomSessionManager sessionMaManager() {
        CustomSessionManager customSessionManager = new CustomSessionManager();
        // session的过期时间
        //   -1  表示永不过期
        //   0   表示浏览器断开连接就会失效
        //   >0   表示设置具体的过期时间
        customSessionManager.setGlobalSessionTimeout(7 * 24 * 60 * 60 * 1000);
        customSessionManager.setSessionIdCookieEnabled(true);
        // 禁用session
        customSessionManager.setSessionIdUrlRewritingEnabled(true);
        return customSessionManager;
    }
}
